package com.pan.admin.generator.context;

import com.gitee.apanlh.spring.BeanContextUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.gitee.apanlh.web.model.vo.RequestVO;
import com.pan.admin.generator.config.ApiGenFieldTemplateConfig;
import com.pan.admin.generator.constant.ApiGenEnum;
import com.pan.admin.generator.constant.ApiGenFieldTemplateTypeEnum;
import com.pan.admin.generator.entity.ApiGenField;
import com.pan.admin.generator.entity.ApiGenTemplate;
import com.pan.admin.generator.strategy.ApiGenApiChannel;
import com.pan.admin.generator.strategy.ApiGenOrgStrategy;
import com.pan.admin.generator.strategy.ApiGenPlatStrategy;
import com.pan.admin.generator.strategy.ApiGenStrategy;
import com.pan.admin.generator.util.ApiGenHttpPinyinUtils;
import com.pan.admin.generator.util.VelocityInitializer;
import com.pan.admin.module.loanProduct.entity.LoanProduct;
import com.pan.admin.module.loanProduct.service.LoanProductService;
import org.apache.velocity.VelocityContext;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 *  API生成对接代码上下文
 *
 *  @author Pan
 */
@Component
public class ApiGenContext {

    private static Map<ApiGenEnum, ApiGenStrategy> apiGenContext = MapUtils.newEnumMap(ApiGenEnum.class);

    private LoanProductService loanProductService;

    private ApiGenContext(LoanProductService loanProductService) {
        super();
        apiGenContext.put(ApiGenEnum.API_ORG, BeanContextUtils.getBean(ApiGenOrgStrategy.class));
        apiGenContext.put(ApiGenEnum.API_PLAT_V3, BeanContextUtils.getBean(ApiGenPlatStrategy.class));
        apiGenContext.put(ApiGenEnum.API_PLAT_V2_PULL, BeanContextUtils.getBean(ApiGenPlatStrategy.class));
        apiGenContext.put(ApiGenEnum.API_CHANNEL_V3, BeanContextUtils.getBean(ApiGenApiChannel.class));
        apiGenContext.put(ApiGenEnum.API_CHANNEL_V2_PULL, BeanContextUtils.getBean(ApiGenApiChannel.class));
        apiGenContext.put(ApiGenEnum.CHANNEL_FEDERATE, BeanContextUtils.getBean(ApiGenOrgStrategy.class));
        this.loanProductService = loanProductService;
    }

    /**
     *  根据生成类型获取模板
     *
     *  @param  apiGenEnum                  生成类型枚举
     *  @param  apiGenFieldTemplateTypeEnum     字段模板枚举
     *  @return List
     */
    public List<ApiGenField> listFieldTemplate(ApiGenEnum apiGenEnum, ApiGenFieldTemplateTypeEnum apiGenFieldTemplateTypeEnum) {
        ApiGenStrategy apiGenStrategy = apiGenContext.get(apiGenEnum);

        //  获取对应字段模板
        ApiGenFieldTemplateConfig apiGenFieldTemplateConfig = ApiGenFieldTemplateConfig.ofEnum(apiGenFieldTemplateTypeEnum);
        return apiGenStrategy.listFieldTemplate(apiGenFieldTemplateConfig);
    }

    /**
     *  获取模板文件名称
     *
     *  @param  vmTemplateName   vm模板名称
     *  @param  customName       自定义名称
     *  @param  apiGenEnum       生成类型枚举
     *  @return
     */
    public String getTemplateFileName(String vmTemplateName, String customName, ApiGenEnum apiGenEnum) {
        ApiGenStrategy apiGenStrategy = apiGenContext.get(apiGenEnum);
        return apiGenStrategy.getFileName(vmTemplateName, customName);
    }

    /**
     *  获取视图模板
     *
     *  @param  apiGenTemplate  模板对象
     *  @param  apiGenEnum      生成类型枚举
     *  @return Map
     */
    public Map<String ,String> getViewTemplate(ApiGenTemplate apiGenTemplate, ApiGenEnum apiGenEnum) {
        ApiGenStrategy apiGenStrategy = apiGenContext.get(apiGenEnum);

        //  初始模板
        VelocityInitializer.initVelocity();
        //  解析上下文
        VelocityContext vmContext = new VelocityContext();
        //  解析生成模板上下文
        apiGenStrategy.parseGenTemplateContext(apiGenTemplate, vmContext);
        //  获取视图模板
        Map<String, String> viewTemplate = apiGenStrategy.viewTemplate(apiGenTemplate, vmContext);
        return viewTemplate;
    }

    /**
     *  获取模板对象
     *
     *  @author Pan
     *  @param  requestVO   请求实体
     *  @param  apiGenEnum  生成类型枚举
     *  @return AbstractApiGenTemplate
     */
    public ApiGenTemplate getTemplate(RequestVO requestVO, ApiGenEnum apiGenEnum) {
        //  获取模板对象
        ApiGenTemplate apiGenTemplate = requestVO.toBean(ApiGenTemplate.class);
        if (ValidParam.isNull(apiGenTemplate)) {
            throw new NullPointerException("无法获取模板对象");
        }

        apiGenTemplate.setPackageName(apiGenEnum.getPackageName());

        //  设置简称
        if (ValidParam.isEmpty(apiGenTemplate.getCustomChineseName())) {
            throw new NullPointerException("缺失简称");
        }
        apiGenTemplate.setCustomName(ApiGenHttpPinyinUtils.getCustomName(apiGenTemplate.getCustomChineseName()));

        //  获取主体信息
        Long productPlanId = apiGenTemplate.getProductPlanId();
        if (ValidParam.isNotNull(productPlanId)) {
            LoanProduct loanProduct = loanProductService.getByLoanPlanId(productPlanId);
            if (ValidParam.isNull(loanProduct)) {
                throw new IllegalArgumentException("获取计划参数异常");
            }
            apiGenTemplate.setProductId(loanProduct.getId());
        }
        return apiGenTemplate;
    }
}
